#ifndef _STFS_COM_H
#define _STFS_COM_H

#include "crossplat_def.h"

#include <assert.h>
#include <iostream>
#include <fstream>
#include <string.h>
#include <list>
#include <map>
#include <vector>
#include <string>
using namespace std;
const int MAX_CAMERA_NUM = 32;
#pragma pack(4)
typedef enum data_source_id_
{
	DATA_SOURCE_NONE     = 0x00,			//无定义，即未使用
	DATA_SOURCE_RECORD   = 0x01,			//录像码流
	DATA_SOURCE_REDU     = 0x02,			//冗余流
	DATA_SOURCE_BACKUP   = 0x04,			//备份流
	DATA_SOURCE_JUMPTIME = 0x40,			//因时间跳变录像导致录像重叠.
	DATA_SOURCE_MERGE    = 0x80,			//拼接录像段
}DATA_SOURCE_ID;


typedef enum _RECORD_TYPE_
{
	RECORD_NONE			= 0x0000,		//没有录像 
	RECORD_SCHEDULE		= 0x0001,		//定时录像
	RECORD_MANUAL		= 0x0002,		//手动录像，正常录像
	RECORD_MOTION		= 0x0004,	    //移动侦测报警录像
	RECORD_IOALARM		= 0x0008,		//传感器报警录像
	RECORD_SHELTER		= 0x0010,		//遮挡报警录像
	//后续扩展支持
	RECORD_BEHAVIOR_01	= 0x0020,		//行为分析录像
	RECORD_BEHAVIOR_02	= 0x0040,		//行为分析录像
	RECORD_SENSOR_00    = 0x0080,       //传感器1`
	RECORD_SENSOR_02    = 0x0100,       //传感器2
	RECORD_SENSOR_03    = 0x0200,       //
	RECORD_XX			= 0xFF00,		//
}RECORD_TYPE;

//  typedef enum _playback_type_
// {
// 	REPLAY_NULL = 0,					//未设置
// 	REPLAY_STOP,						//停止
// 	REPLAY_PLAY,						//播放 1
// 	REPLAY_PAUSE,						//暂停
// 	REPLAY_BACKUP,						//备份
//
// 	REPPAY_DOWNLOAD,					//远程下载
// 	REPLAY_NORMAL  = 0x10,				//正常回放
// 	REPLAY_ONEFRAME= 0x20,				//单帧播放
// 	REPLAY_SLOW    = 0x40,				//慢进 2, 4, 8, 16, 32
// 	REPLAY_FAST    = 0x80,				//快进 2, 4, 8, 16, 32
// 	REPLAY_REBACK  = 0x100,				//回退 8, 16, 32
//
//  }PLAYBACK_MODE;

//磁盘类型：本地(SATA）、E_SATA、IP_SAN、NAS、USB等（只读）
// typedef enum _disk_bus_type_
// {
// 	BUS_TYPE_SATA  = 0,		//本地磁盘
// 	BUS_TYPE_ESATA = 1,		//可以支持热插拨的SATA接口
// 	BUS_TYPE_USB   = 2,		//USB接口
// 	BUS_TYPE_IPSAN = 3,		//IPSAN网络接口
// 	BUS_TYPE_NAS   = 4,		//NAS
// }E_DISK_BUS_TYPE;

typedef enum _RECORD_PROCESS_
{
	REC_PROCESS_NONE = 0,
	REC_PROCESS_OPEN,

	REC_PROCESS_MULSEG_START,	//多段录像开始
	REC_PROCESS_MULSEG_END,		//多段录像结束

	REC_PROCESS_CLOSED,
}E_RECORD_PROCESS;

typedef struct _rec_file_info_
{
	uint8_t			channel;		//通道号
	uint8_t			status;			//状态：RECORD_FILE_STATUS
	uint8_t			diskIndex;		//磁盘编号
	uint8_t			dataSource;		//数据来源	DATA_SOURCE_ID

	uint8_t			procstep;		//流程　0 ,1 ,2 ,3
	uint8_t			enableText:1;	//是否使用文本信息(只读）
	uint8_t         timeZone:7;		//时区
	uint16_t		recordType;		//录像类型 record_type_

	uint32_t		indexNo:24;		//索引序号
	uint32_t		segIndex:8;		//录像段编号

	uint32_t		length;			//文件数据长度
	union
	{
		uint32_t	endOffset;		//文件结束的位置
		uint32_t    merge_hour_tm; // 整点时间
	};

	int64_t			tmStart;		//起始时间 ms级
	int64_t			tmEnd;			//结束时间 ms级
	uint32_t        recordSN;       //录像序列号
	char			deviceSN[MAX_DEVSN_LEN];	//设备序列号
	char			text[MAX_REC_TAG_LEN];		//文本内容
//	string          text;			//文本内容
#ifdef _HAVE_TEXT_INFO
	uint32_t		deviceID;		//设备编号
	uint32_t		cameraID;		//摄像机编号

//	char			deviceSN[MAX_DESC_LEN];	//设备序列号
	char			deviceName[MAX_DESC_LEN];	//设备名称
	char			cameraName[MAX_DESC_LEN];	//摄像机名称	
#endif
}REC_FILE_INFO,*PREC_FILE_INFO;
typedef std::list<REC_FILE_INFO> REC_FILE_LIST, *LPREC_FILE_LIST;

typedef struct _REC_DAY_IN_
{
	time_t tm_day_start;  // 日期的开始
	time_t tm_day_end;	  // 日期的结束　
}REC_DAY;
typedef vector<REC_DAY> VEC_REC_DAY_T;


// typedef struct _download_record_
// {
// 	int	    downloadType;	//DOWNLOAD_TYPE
//
// 	int64_t	startTime;		//起始时间
// 	int64_t	endTime;		//结束时间(在downloadType为TVT_DOWNLOAD_PLAY时无效）
//
// 	uint16_t	bSynchro;		//是否同步下载（同步则多通道统一排序下载，通常用于回放）
// 	uint16_t	channelNum;		//有效通道数目（只读）
// 	//streamType[i]代表地i通道的码流，TVT_STREAM_TYPE
// }DOWNLOAD_RECORD;

typedef struct disk_info_
{
	uint16_t	index;			            //序号（物理节点）

	uint16_t	type;			            //磁盘类型：本地(SATA）、USB, E_SATA、IP_SAN、NAS、DVD、等（只读）
	uint16_t	property;		            //属性：读写, 只读、冗余、
	uint16_t	partitionNum;	            //分区数目
	uint16_t	group;			            //盘组：<= diskNum
	int16_t		status;			            //状态：0 正常, 1 正在初始化, 2未初始化 -1 未激活
	uint16_t	extraStatus;                //记录硬盘的附加状态：休眠
	uint16_t	port;			            //磁盘端口号

	uint32_t   totalSpace;			         //总容量：MB（只读）

	uint32_t   dataSpace;					//录像总容量：MB（只读）
	uint32_t   dataFreeSpace;		        //录像剩余容量：MB（只读）

	uint32_t   picSpace;                   //图片总容量：MB（只读）
	uint32_t   picFreeSpace;               //图片剩余容量：MB（只读）

	uint32_t   comPartSpace;               //公共盘大小
	uint32_t   comPartFree;                //公共盘剩余
	char       diskName[40];				//磁盘的名字./dev/sda
	char	   deviceText[32];				//设备描述信息

	char       linkInfo[256];               //端口信息 
	///sys/devices/platform/ahci.0/ata1/host0/target0:0:0/0:0:0:0/block/sda
	///sys/devices/platform/hiusb-ehci.0/usb1/1-2/1-2.3/1-2.3.1/1-2.3.1:1.0/host3/target3:0:0/3:0:0:0/block/
	uint64_t   recFileLBA;					//录像文件的首地址
	uint32_t   recFileSecs;					//预分配文件的大小占用的扇区数　　()64MB，128MB ,256MB，512MB,1GB等　/512）

	uint64_t   recIndexLBA;					//录像索引文件地址
	uint64_t   dbgLogLBA;					//调试日志地址
	uint64_t   sysLogLBA;                
	uint32_t   init_time;                   //初始化时间
#ifdef _EXTERN_FUNC
	char			deviceURL[MAX_DESC_LEN];	//磁盘网络地址
	char			iqn[MAX_DESC_LEN+4];		//磁盘iqn
#endif
}DISK_INFO,*PDISK_INFO;

//32Bytes
typedef struct _FS_PARTITION_
{
	int		 fsType;			//文件系统的类型 0:STFS　1：NTFS  2:FAT32 3:exFAT32 4:
	uint32_t freeSpaceMB;		//剩余大小
	uint64_t startLBA;			//开始LBA
	uint64_t totalSecs;			//分区总共扇区
	uint32_t reseverd[2];		//保留2个int　8个字节．
}FS_PARTITION,*PFS_PARTITION;
#pragma pack()

class CCross_LockAuto
{
public:
	explicit CCross_LockAuto(CCross_Lock* pLock);
	~CCross_LockAuto();

private:
	CCross_Lock* m_pLock;
};

#ifdef _HAVE_SHOW_TIME_
#define PRINT_TMSTR(start,end,strTitle) PrintTimeMs(start,end,strTitle)
#else
#define PRINT_TMSTR(start,end,strTitle)
#endif
#ifdef __cplusplus
extern "C" {
#endif
int GetCurDayTm(time_t * pTmSartDay, time_t * pTmEndDay);
int GetCurHourTmSec(uint32_t* pTmSartDay, uint32_t* pTmEndDay, time_t cur_tm);
int GetCurMinsTmSec(uint32_t* pTmSartDay, uint32_t* pTmEndDay, time_t cur_tm, int mins);
int GetDayTimeSec(time_t * pTmSartDay, time_t * pTmEndDay,int year,int month, int day);
int GetDayTimeMs(int64_t * pTmSartDay, int64_t * pTmEndDay,int year,int month, int day);
int GetMonthTime(int64_t & monthTmStart, int64_t & monthTmEnd,int year, int month);
int GetMaxDayOfMonth(int year, int month);
void PrintCurTime();
int64_t GetmSecond();
int CheckDiskSpace(string devPath, uint64_t * pFreeSize,uint64_t * pTotalSpace);
void Convert_utc_2_bcdtm( uchar_t* destBcdTm,time_t srcTm);
int ConvertTimeStr(time_t tm, char * datebuf,bool bUTC = false);
int ConvertDateStr(int64_t timeMs, char * datebuf,bool bUTC = false);
int ConvertRecSegStr(int64_t tmStart, int64_t tmEnd, char * dateBuf, int size, bool bUTC = false);
int ConvertSecTmStr(time_t timeSec, char * datebuf,int size,bool bUTC =false);
time_t ConvertDayTm(time_t curTime);
int GetCurDayStarTm(int64_t * tmStart);
int GetCurDayEndTm(int64_t * tmEnd);
int GetCurHourArea(int64_t & tmStart, int64_t & tmEnd, int64_t srcTm);

int GetTmByTime(struct tm * curTm, int64_t  timeMS);
bool IsEffectiveTimeSeg(int64_t tmStart,int64_t tmEnd);
int convert_ms_to_bcd(int8_t *tmbcd,int64_t  convertMs);

int Random(int m, int n);
void GetFileDestPath(char * destPath, const char * srcPath);
int GetRecFileName(char * fileName,char * path, uint32_t fileIndex);

int GetStorageName(char * destStorage,const char * srcStoarge);
uint8_t GetTimeZone();
bool effect_bit(int i, int32_t bit);
int convert_sec_to_bcd(int8_t *tmbcd,time_t convertSec);
#ifdef _WIN32

int ShowLocalTime(int64_t dvrTime);
int ShowNowLocalTime();
int GetStrRecordType(int recType,char* strBuf);
char *  GetStatusStr(int diskStatus);
int convert_time_to_bcd(int8_t *tmbcd,time_t convertTm);

#endif

#ifdef __cplusplus
}
#endif

#endif //_STFS_COM_H
